#ifndef _GL_TEXTURE_H_
#define _GL_TEXTURE_H_

#include "..\glew\glew.h"

#include "..\cuCommon\cuTypes.h"

#include "glSubresourceData.h"

typedef struct GL_SAMPLE_DESC 
{
  GLuint Count;
  GLuint Quality;
  GL_SAMPLE_DESC()
  {
    Count = 1;
    Quality = 0;
  }
} GL_SAMPLE_DESC, *LPGL_SAMPLE_DESC;

enum GL_TARGET_TEXTURE
{
	GL_TARGET_UNKNOWN		 = 0,
  GL_TARGET_TEXTURE_1D = GL_TEXTURE_1D,
  GL_TARGET_TEXTURE_2D = GL_TEXTURE_2D,
  GL_TARGET_TEXTURE_3D = GL_TEXTURE_3D,
  GL_TARGET_TEXTURE_1D_ARRAY = GL_TEXTURE_1D_ARRAY_EXT,
  GL_TARGET_TEXTURE_2D_ARRAY = GL_TEXTURE_2D_ARRAY_EXT,
  GL_TARGET_TEXTURE_CUBE_MAP = GL_TEXTURE_CUBE_MAP,
};

struct GL_TEXTURE_DESC 
{
  GLenum Target;
  GLuint Width;
  GLuint Height;
  GLuint Depth;
  GLuint Border;
  GLuint MipLevels;
  GLuint ArraySize;
  GLenum Format;

  GL_TEXTURE_DESC(GLenum target = GL_TEXTURE_2D)
  {
    Target = target;
    Width  = 0;
    Height = 0;
    Depth  = 0;
    Border = 0;
    MipLevels = 1;
    ArraySize = 1;
    Format = GL_RGBA;
  }
  GL_TEXTURE_DESC( GLuint w, GL_TARGET_TEXTURE target = GL_TARGET_TEXTURE_1D )
  {
    Target = target;
    Width  = w;
    Height = 0;
    Depth  = 0;
    Border = 0;
    MipLevels = 1;
    ArraySize = 1;
    Format = GL_RGBA;
  }

  GL_TEXTURE_DESC( GLuint w, GLuint h, GL_TARGET_TEXTURE target = GL_TARGET_TEXTURE_2D )
  {
    Target = target;
    Width  = w;
    Height = h;
    Depth  = 0;
    Border = 0;
    MipLevels = 1;
    ArraySize = 1;
    Format = GL_RGBA;
  }

  GL_TEXTURE_DESC( GLuint w, GLuint h, GLuint d, GL_TARGET_TEXTURE target = GL_TARGET_TEXTURE_3D )
  {
    Target = target;
    Width  = w;
    Height = h;
    Depth  = d;
    Border = 0;
    MipLevels = 1;
    ArraySize = 1;
    Format = GL_RGBA;
  }
};

typedef struct GL_FILTER_DESC 
{
  GLenum Min;
  GLenum Mag;
  GL_FILTER_DESC()
  {
    Default();
  }
  GL_FILTER_DESC(GLenum minFilter, GLenum magFilter)
  {
    Mag = magFilter;
    Min = minFilter;
  }
  void Default()
  {
    Min = GL_LINEAR;
    Mag = GL_LINEAR;
  }
} GL_FILTER_DESC;

typedef struct GL_SAMPLER_DESC 
{
  GL_FILTER_DESC Filter;
  GLenum AddressR;
  GLenum AddressS;
  GLenum AddressT;
  //FLOAT MipLODBias;
  GLuint MaxAnisotropy;
  GLenum ComparisonFunc;
  float BorderColor[4];
  float MinLOD;
  float MaxLOD;
  GL_SAMPLER_DESC()
  {
    Default();
  }
  GL_SAMPLER_DESC(GLenum minFilter, GLenum magFilter) :
                  Filter(minFilter, magFilter)
  {
    Default();
  }
  void Default(void)
  {
    AddressR = GL_CLAMP_TO_EDGE;
    AddressS = GL_CLAMP_TO_EDGE;
    AddressT = GL_CLAMP_TO_EDGE;
    MaxAnisotropy = 1.0f;
    ComparisonFunc = GL_NONE;
    BorderColor[0] = BorderColor[1] = BorderColor[2] = BorderColor[3] = 0.0f;
    MinLOD = 0.0f;
    MaxLOD = 3.402823466e+38F; //FLT_MAX;
    Filter.Default();
  }
} GL_SAMPLER_DESC;


void  glSetSampler( GLenum target, 
                    const GL_SAMPLER_DESC * pSampler );

GLint glCreateTexture( const GL_TEXTURE_DESC     * pDesc,
                       const GL_SUBRESOURCE_DATA * pSubResource,
                       const GL_SAMPLER_DESC     * pSampler );

#endif